package shan.rpc.yurpc.server;

import io.vertx.core.Handler;
import io.vertx.core.buffer.Buffer;
import io.vertx.core.http.HttpServerRequest;
import io.vertx.core.http.HttpServerResponse;
import shan.rpc.yurpc.RpcApplication;
import shan.rpc.yurpc.model.RpcRequest;
import shan.rpc.yurpc.model.RpcResponse;
import shan.rpc.yurpc.registry.LocalRegistry;
import shan.rpc.yurpc.serializer.JdkSerializer;
import shan.rpc.yurpc.serializer.Serializer;
import shan.rpc.yurpc.serializer.SerializerFactory;

import java.io.IOException;
import java.lang.reflect.Method;

/**
 * http请求
 */
public class HttpServerHandler implements Handler<HttpServerRequest> {


    @Override
    public void handle(HttpServerRequest request) {
        //指定序列化器
        final Serializer serializer= SerializerFactory.getInstance(RpcApplication.getRpcConfig().getSerializer());

        //记录日志
        System.out.println("Received request:"+request.method()+" "+request.uri());

        //异步处理http请求
        request.bodyHandler(body->{
            byte[] bytes=body.getBytes();
            RpcRequest rpcRequest=null;
            try {
                rpcRequest=serializer.deserialize(bytes,RpcRequest.class);
            }catch (Exception e){
                e.printStackTrace();
            }
            //构造相应结果对象
            RpcResponse rpcResponse=new RpcResponse();
            //如果请求为null,直接返回
            if(rpcRequest==null){
                rpcResponse.setMessage("Request is null");
                doResponse(request,rpcResponse,serializer);
                return;
            }
            try {
                //获取想要调用的服务实现类，通过反射调用
                Class<?> implClass= LocalRegistry.get(rpcRequest.getServiceName());
                Method method=implClass.getMethod(rpcRequest.getMethodName(),rpcRequest.getParameterTypes());
                Object result=method.invoke(implClass.newInstance(),rpcRequest.getArgs());
                rpcResponse.setData(result);
                rpcResponse.setDataType(method.getReturnType());
                rpcResponse.setMessage("ok");
            } catch (Exception e){
                e.printStackTrace();
                rpcResponse.setMessage(e.getMessage());
                rpcResponse.setException(e);
            }
            doResponse(request,rpcResponse,serializer);
        });
    }

    /**
     * 响应
     */
    void doResponse(HttpServerRequest request,RpcResponse rpcResponse,Serializer serializer){
        HttpServerResponse httpServerResponse=request.response()
                .putHeader("content-type","application/json");
        try{
            //序列化
            byte[] serialized=serializer.serialize(rpcResponse);
            httpServerResponse.end(Buffer.buffer(serialized));
        }catch (IOException e){
            e.printStackTrace();
            httpServerResponse.end(Buffer.buffer());
        }
    }
}
